#ifndef DBUSSIGNALMODEL_HPP
#define DBUSSIGNALMODEL_HPP

#include <QAbstractItemModel>
#include "common.hpp"
#include <qdom.h>
#include <dbuslog.hpp>
//class DbusTestModelItem;
class DbusSignalItem : public QObject
{
    Q_OBJECT
public:

    DbusSignalItem(DbusTestModelItem *item,QObject *parent = nullptr):QObject(parent),m_item(item)
    {

        QDBusConnection bus("NONE");
        QString signature="";
        foreach (auto var, m_item->m_data.argTypes) {
            signature+=var;
        }
        if(m_item->m_data.mBus == DBUS_NAME_SESSION)
        {
            bus = QDBusConnection::connectToBus (QDBusConnection::SessionBus,DBUS_NAME_SESSION);
        }else if(m_item->m_data.mBus == DBUS_NAME_SYSTEM)
        {
            bus = QDBusConnection::connectToBus (QDBusConnection::SystemBus,DBUS_NAME_SYSTEM);
        }else
        {
            bus = QDBusConnection::connectToBus (m_item->m_data.mBus,m_item->m_data.mBus);
        }
        if(!bus.isConnected ())
        {
            qDebug()<<bus.lastError ().message ();
            return;
        }
        QString service = m_item->m_data.mService;
        QString path = m_item->m_data.mPath;
        QString interface = m_item->m_data.mInterface;
        QString name = m_item->m_data.mName;
        qDebug()<<service<<path<<interface<<name;
        bool b = bus.connect(service,path,interface,name, signature,this, SLOT(onSignalCall(QDBusMessage)));
        if(!b)
        {
            qDebug()<<bus.lastError ().message ();
        }

    }
    ~DbusSignalItem()
    {
        QDBusConnection bus("NONE");
        QString signature="";
        foreach (auto var, m_item->m_data.argTypes) {
            signature+=var;
        }
        if(m_item->m_data.mBus == DBUS_NAME_SESSION)
        {
            bus = QDBusConnection::connectToBus (QDBusConnection::SessionBus,DBUS_NAME_SESSION);
        }else if(m_item->m_data.mBus == DBUS_NAME_SYSTEM)
        {
            bus = QDBusConnection::connectToBus (QDBusConnection::SystemBus,DBUS_NAME_SYSTEM);
        }else
        {
            bus = QDBusConnection::connectToBus (m_item->m_data.mBus,m_item->m_data.mBus);
        }
        if(!bus.isConnected ())
        {
            signalLog()<<bus.lastError ().message ();
            return;
        }
        QString service = m_item->m_data.mService;
        QString path = m_item->m_data.mPath;
        QString interface = m_item->m_data.mInterface;
        QString name = m_item->m_data.mName;
        bool b = bus.disconnect(service,path,interface,name, signature,this, SLOT(onSignalCall(QDBusMessage)));
        if(!b)
        {
            signalLog()<<bus.lastError ().message ();
        }
    }
    inline bool operator==(DbusTestModelItem *item) const Q_DECL_NOTHROW { return m_item == item; }
signals:
    void signalCall(DbusTestModelItem *item,const QDBusMessage &msg);
public slots:
    void onSignalCall(const QDBusMessage &msg)
    {
        emit signalCall(m_item,msg);
    }
private:
    DbusTestModelItem *m_item;
};

class DbusSignalModel : public QAbstractItemModel
{
    Q_OBJECT
public:
    explicit DbusSignalModel(QObject *parent = nullptr);
    ~DbusSignalModel();
signals:
    void signalCall(DbusTestModelItem *item,const QDBusMessage &msg);
public slots:
protected:
    DbusTestModelItem *root;

    // QAbstractItemModel interface
public:
    void connectAll();
    void disconnectAll();
    void connectItem(DbusTestModelItem *item);

    QVector<DbusTestModelItem *> getItemList();
    DbusTestModelItem *getItem(const QModelIndex &index);
    QModelIndex index(int row, int column, const QModelIndex &parent) const override;
    QModelIndex parent(const QModelIndex &child) const override;
    int rowCount(const QModelIndex &parent) const override;
    int columnCount(const QModelIndex &parent) const override;
    QVariant data(const QModelIndex &index, int role) const override;
    bool setData(const QModelIndex &index, const QVariant &value, int role) override;
    bool insertRows(int row, int count, const QModelIndex &parent) override;
    bool removeRows(int row, int count, const QModelIndex &parent) override;
    bool moveRows(const QModelIndex &sourceParent, int sourceRow, int count, const QModelIndex &destinationParent, int destinationChild) override;
    Qt::ItemFlags flags(const QModelIndex &index) const override;
    void append(DbusTestModelItem *item,const QModelIndex &index = QModelIndex());
    void insertItem(int position,DbusTestModelItem *item,const QModelIndex &index = QModelIndex());

    bool isSkip(const QModelIndex &index) const;
    void setSkip(const QModelIndex &index,bool isSkip);

    QModelIndexList getResultIndex(DbusTestModelItem *item);

    void importXML(QString context);
    QString exportXML();

    // QAbstractItemModel interface
public:
    QVariant headerData(int section, Qt::Orientation orientation, int role) const override;
    bool moveColumns(const QModelIndex &sourceParent, int sourceColumn, int count, const QModelIndex &destinationParent, int destinationChild) override;
    inline int getColumnId(int index) const;
    inline int getColumnIndex(int id) const;
    QVariant getHeader(int id) const
    {
        switch (id) {
        case 0:
            return "Skip";
            break;
        case 1:
            return "category";
            break;
        case 2:
            return "method";
            break;
        case 3:
            return "param type";
            break;
        case 4:
            return "parameter";
            break;
        case 5:
            return "Addr";
            break;
        case 6:
            return "Service";
            break;
        case 7:
            return "Path";
            break;
        case 8:
            return "Interface";
            break;
        case 9:
            return "time";
            break;
        default:
            break;
        }
        return QVariant();
    }

private:
    QList<DbusSignalItem*> m_dbusSignals;
    QList<int> m_ColumnsId;
};





































#endif // DBUSSIGNALMODEL_HPP
